﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.IO;
using System.Web;
using System.Net;

namespace DMS.Business.WebControls
{
    [ToolboxData("<{0}:FileLink runat=server></{0}:FileLink>")]
    public class FileLink : LinkButton
    {
        #region 成员属性
        /// <summary>
        /// 文件的相对路径，不包括服务器路径
        /// </summary>
        public string FileUrl
        {
            get
            {
                if (this.ViewState["FileUrl"] == null)
                {
                    return string.Empty;
                }
                else
                {
                    return this.ViewState["FileUrl"].ToString();
                }
            }
            set
            {
                this.ViewState["FileUrl"] = value;
            }
        }
        /// <summary>
        /// 下载文件名
        /// </summary>
        public string FileName
        {
            get
            {
                if (this.ViewState["FileName"] == null)
                {
                    return string.Empty;
                }
                else
                {
                    return this.ViewState["FileName"].ToString();
                }
            }
            set
            {
                this.ViewState["FileName"] = value;
            }
        }

        private string _FileServer = string.Empty;
        /// <summary>
        /// 文件服务器路径
        /// </summary>
        public string FileServer
        {
            get
            {
                if (string.IsNullOrEmpty(this._FileServer)
                    && !string.IsNullOrEmpty(ConfigurationManager.AppSettings["FileServer"]))
                {
                    return ConfigurationManager.AppSettings["FileServer"].ToString();
                }

                return this._FileServer;
            }
            set
            {
                this._FileServer = value;
            }
        }

        private string _FileServerAccount = string.Empty;
        /// <summary>
        /// 文件服务器帐号
        /// </summary>
        public string FileServerAccount
        {
            get
            {
                if (string.IsNullOrEmpty(this._FileServerAccount)
                    && !string.IsNullOrEmpty(ConfigurationManager.AppSettings["FileServerAccount"]))
                {
                    return ConfigurationManager.AppSettings["FileServerAccount"].ToString();
                }

                return this._FileServerAccount;
            }
            set
            {
                this._FileServerAccount = value;
            }
        }

        private string _FileServerPassword = string.Empty;
        /// <summary>
        /// 文件服务器帐号密码
        /// </summary>
        public string FileServerPassword
        {
            get
            {
                if (string.IsNullOrEmpty(this._FileServerPassword)
                    && !string.IsNullOrEmpty(ConfigurationManager.AppSettings["FileServerPassword"]))
                {
                    return ConfigurationManager.AppSettings["FileServerPassword"].ToString();
                }

                return this._FileServerPassword;
            }
            set
            {
                this._FileServerPassword = value;
            }
        }

        private int _FileServerTimeOut = int.MinValue;
        /// <summary>
        /// 文件服务器超时
        /// </summary>
        public int FileServerTimeOut
        {
            get
            {
                if (this._FileServerTimeOut == int.MinValue)
                {
                    if (ConfigurationManager.AppSettings["FileServerTimeOut"] != null)
                    {
                        return Convert.ToInt32(ConfigurationManager.AppSettings["FileServerTimeOut"].ToString());
                    }
                    else
                    {
                        return 1500000;
                    }
                }

                return this._FileServerTimeOut;
            }
            set
            {
                this._FileServerTimeOut = value;
            }
        }
        private int _Buffer = 1024;
        /// <summary>
        /// 传输缓冲
        /// </summary>
        public int Buffer
        {
            get
            {
                return this._Buffer;
            }
            set
            {
                this._Buffer = value;
            }
        }
        
        #endregion

        #region 事件
        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            string path = this.GetFileFullPath();
            this.Download(path, this.FileName);
        }
        #endregion

        #region 私有成员
        /// <summary>
        /// 获取文件全路径
        /// </summary>
        /// <returns></returns>
        private string GetFileFullPath()
        {
            return string.Format("{0}/{1}", this.FileServer.TrimEnd("/".ToCharArray()), this.FileUrl.Trim("~".ToCharArray()).TrimStart("/".ToCharArray()));
        }
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="fileName">下载名称</param>
        private void Download(string filePath, string fileName)
        {
            // 获取扩展名
            Uri uri = new Uri(filePath);
            string extName = VirtualPathUtility.GetExtension(uri.AbsolutePath).Trim(".".ToCharArray());

            // 获取文件名
            if (string.IsNullOrEmpty(fileName))
            {
                fileName = VirtualPathUtility.GetFileName(uri.AbsolutePath);
            }
            else
            {
                fileName = string.Format("{0}.{1}", fileName, extName);
            }

            // 获取文件字符流
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(filePath);
            request.Timeout = this.FileServerTimeOut;
            request.Credentials = CredentialCache.DefaultCredentials;
            if (!string.IsNullOrEmpty(this.FileServerAccount))
            {
                request.Credentials = new NetworkCredential(this.FileServerAccount, this._FileServerPassword);
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream stream = response.GetResponseStream();

            // 输出文件
            HttpResponse Response = HttpContext.Current.Response;
            Response.Clear();
            Response.ContentType = string.Format("application/{0}", extName);
            Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", HttpUtility.UrlEncode(fileName)));

            int buffer = this.Buffer;
            while (true)
            {
                byte[] bytes = new byte[buffer];
                int alreadyRead = stream.Read(bytes, 0, buffer);

                // 文件输传完毕
                if (alreadyRead == 0)
                {
                    break;
                }

                // 缓冲满
                if (alreadyRead == buffer)
                {
                    Response.BinaryWrite(bytes);
                }
                else
                {
                    // 最后的字节数
                    byte[] lastBytes = new byte[alreadyRead];
                    for (int i = 0; i < alreadyRead; i++)
                    {
                        lastBytes[i] = bytes[i];
                    }
                    Response.BinaryWrite(lastBytes);
                }
            }
            Response.End();
        }
        #endregion
    }
}
